using System;
using OracleInternal.Common;
using OracleInternal.I18N;

namespace OracleInternal.Network
{
	internal class ConnectPacket : Packet
	{
		internal static readonly int NSPMXTPKTLEN = TNSPacketOffsets.NSPMXCDATA + TNSPacketOffsets.NSPCNV315DAT;

		private bool m_bConnDataOverFlow;

		private string m_connectData;

		private static int maxLen = 421;

		internal ConnectPacket(SessionContext sessCtx, bool onRedirect = false)
			: base(sessCtx)
		{
			m_connectData = sessCtx.m_connectData;
			int num = ((m_connectData != null) ? m_connectData.Length : 0);
			m_bConnDataOverFlow = ((num > TNSPacketOffsets.NSPMXCDATA) ? true : false);
			int pktSize = TNSPacketOffsets.NSPCNV315DAT + ((!m_bConnDataOverFlow) ? num : 0);
			CreateBuffer(pktSize, 1, onRedirect ? Packet.NSPFRDR : 0, sessCtx);
			m_dataBuffer[TNSPacketOffsets.NSPCNVSN] = (byte)((uint)(sessCtx.m_myversion / 256) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNVSN + 1] = (byte)((uint)(sessCtx.m_myversion % 256) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNLOV] = (byte)((uint)(sessCtx.m_loversion / 256) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNLOV + 1] = (byte)((uint)(sessCtx.m_loversion % 256) & 0xFFu);
			if (sessCtx.m_transportAdapter.UrgentDataSupported() && !sessCtx.m_conops.SNOConfig.DisableOOB)
			{
				sessCtx.m_options |= TNSPacketOffsets.NSGRECVATTN;
			}
			m_dataBuffer[TNSPacketOffsets.NSPCNOPT] = (byte)((uint)(sessCtx.m_options / 256) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNOPT + 1] = (byte)((uint)(sessCtx.m_options % 256) & 0xFFu);
			int sessionDataUnit = sessCtx.m_sessionDataUnit;
			int transportDataUnit = sessCtx.m_transportDataUnit;
			int num2 = ((sessionDataUnit > ConnectionOption.NSPOLDMXSDULN) ? ConnectionOption.NSPOLDMXSDULN : sessionDataUnit);
			int num3 = ((transportDataUnit > ConnectionOption.NSPOLDMXTDULN) ? ConnectionOption.NSPOLDMXTDULN : transportDataUnit);
			m_dataBuffer[TNSPacketOffsets.NSPCNSDU] = (byte)(num2 / 256);
			m_dataBuffer[TNSPacketOffsets.NSPCNSDU + 1] = (byte)(num2 % 256);
			m_dataBuffer[TNSPacketOffsets.NSPCNLSD + 3] = (byte)((uint)sessionDataUnit & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNLSD + 2] = (byte)((uint)HelperClass.URShift(sessionDataUnit, 8) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNLSD + 1] = (byte)((uint)HelperClass.URShift(sessionDataUnit, 16) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNLSD] = (byte)((uint)HelperClass.URShift(sessionDataUnit, 24) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNTDU] = (byte)(num3 / 256);
			m_dataBuffer[TNSPacketOffsets.NSPCNTDU + 1] = (byte)(num3 % 256);
			m_dataBuffer[TNSPacketOffsets.NSPCNLTD + 3] = (byte)((uint)transportDataUnit & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNLTD + 2] = (byte)((uint)HelperClass.URShift(transportDataUnit, 8) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNLTD + 1] = (byte)((uint)HelperClass.URShift(transportDataUnit, 16) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNLTD] = (byte)((uint)HelperClass.URShift(transportDataUnit, 24) & 0xFFu);
			byte[] dataBuffer = m_dataBuffer;
			byte nSPCNCFL = TNSPacketOffsets.NSPCNCFL;
			byte[] dataBuffer2 = m_dataBuffer;
			int num4 = TNSPacketOffsets.NSPCNCFL + 1;
			byte b;
			m_dataBuffer[TNSPacketOffsets.NSPCNCFL + 2] = (b = (m_dataBuffer[TNSPacketOffsets.NSPCNCFL + 3] = 0));
			dataBuffer2[num4] = (b = b);
			dataBuffer[nSPCNCFL] = b;
			m_dataBuffer[TNSPacketOffsets.NSPCNNTC] = 79;
			m_dataBuffer[TNSPacketOffsets.NSPCNNTC + 1] = 152;
			m_dataBuffer[TNSPacketOffsets.NSPCNONE] = (byte)((uint)(sessCtx.m_ourone >> 8) & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNONE + 1] = (byte)(sessCtx.m_ourone & 0xFFu);
			m_dataBuffer[TNSPacketOffsets.NSPCNLEN] = (byte)(num / 256);
			m_dataBuffer[TNSPacketOffsets.NSPCNLEN + 1] = (byte)(num % 256);
			m_dataBuffer[TNSPacketOffsets.NSPCNOFF + 1] = TNSPacketOffsets.NSPCNV315DAT;
			if (m_sessionCtx.m_bAnoEnabled)
			{
				m_dataBuffer[TNSPacketOffsets.NSPCNFL0] = (byte)m_sessionCtx.m_ano.m_naFlags;
				m_dataBuffer[TNSPacketOffsets.NSPCNFL1] = (byte)m_sessionCtx.m_ano.m_naFlags;
			}
			else
			{
				m_dataBuffer[TNSPacketOffsets.NSPCNFL0] = TNSPacketOffsets.NSINADISABLEFORCONNECTION;
				m_dataBuffer[TNSPacketOffsets.NSPCNFL1] = TNSPacketOffsets.NSINADISABLEFORCONNECTION;
			}
			if (!m_bConnDataOverFlow && num > 0)
			{
				byte[] array = Conv.GetInstance(871).ConvertStringToBytes(m_connectData, 0, m_connectData.Length);
				int num5 = array.Length;
				for (int i = 0; i < num5; i++)
				{
					m_dataBuffer[TNSPacketOffsets.NSPCNV315DAT + i] = array[i];
				}
			}
		}

		internal ConnectPacket(SessionContext sessCtx, int size)
			: base(sessCtx, (size > 0) ? size : NSPMXTPKTLEN)
		{
		}

		internal override void Send()
		{
			base.Send();
			if (!m_bConnDataOverFlow)
			{
				return;
			}
			byte[] array = Conv.GetInstance(871).ConvertStringToBytes(m_connectData, 0, m_connectData.Length);
			DataPacket dataPacket = new DataPacket(m_sessionCtx, array.Length + Packet.NSPOVR_SZ);
			if (array.Length < maxLen)
			{
				dataPacket.PutDataInBuffer(array, 0, array.Length);
				dataPacket.Send();
				return;
			}
			int num = array.Length;
			int num2 = 0;
			while (num > 0)
			{
				int num3 = ((num > maxLen) ? maxLen : num);
				dataPacket.PutDataInBuffer(array, num2, num3);
				dataPacket.Send();
				num2 += num3;
				num -= num3;
			}
		}

		internal override void Receive()
		{
			base.Receive();
			if (m_type != TNSPacketType.CONNECT)
			{
				throw new NetworkException(12566);
			}
			int num = m_dataBuffer[TNSPacketOffsets.NSPCNVSN] & 0xFF;
			num <<= 8;
			num |= m_dataBuffer[TNSPacketOffsets.NSPCNVSN + 1] & 0xFF;
			int num2 = m_dataBuffer[TNSPacketOffsets.NSPCNLOV] & 0xFF;
			num2 <<= 8;
			num2 |= m_dataBuffer[TNSPacketOffsets.NSPCNLOV + 1] & 0xFF;
			_ = (m_dataBuffer[TNSPacketOffsets.NSPCNOPT] & 0xFF) << 8;
			_ = m_dataBuffer[TNSPacketOffsets.NSPCNOPT + 1];
			int num3;
			int num4;
			if (num < 315)
			{
				num3 = m_dataBuffer[TNSPacketOffsets.NSPCNSDU] & 0xFF;
				num3 <<= 8;
				num3 |= m_dataBuffer[TNSPacketOffsets.NSPCNSDU + 1] & 0xFF;
				num4 = m_dataBuffer[TNSPacketOffsets.NSPCNTDU] & 0xFF;
				num4 <<= 8;
				num4 |= m_dataBuffer[TNSPacketOffsets.NSPCNTDU + 1] & 0xFF;
			}
			else
			{
				num3 = m_dataBuffer[TNSPacketOffsets.NSPCNLSD] & 0xFF;
				num3 <<= 8;
				num3 |= m_dataBuffer[TNSPacketOffsets.NSPCNLSD + 1] & 0xFF;
				num3 <<= 8;
				num3 |= m_dataBuffer[TNSPacketOffsets.NSPCNLSD + 2] & 0xFF;
				num3 <<= 8;
				num3 |= m_dataBuffer[TNSPacketOffsets.NSPCNLSD + 3] & 0xFF;
				num4 = m_dataBuffer[TNSPacketOffsets.NSPCNLTD] & 0xFF;
				num4 <<= 8;
				num4 |= m_dataBuffer[TNSPacketOffsets.NSPCNLTD + 1] & 0xFF;
				num4 <<= 8;
				num4 |= m_dataBuffer[TNSPacketOffsets.NSPCNLTD + 2] & 0xFF;
				num4 <<= 8;
				num4 |= m_dataBuffer[TNSPacketOffsets.NSPCNLTD + 3] & 0xFF;
			}
			m_sessionCtx.m_hisone = (ushort)(m_dataBuffer[TNSPacketOffsets.NSPCNONE] & 0xFFu);
			m_sessionCtx.m_hisone <<= 8;
			m_sessionCtx.m_hisone |= (ushort)(m_dataBuffer[TNSPacketOffsets.NSPCNONE + 1] & 0xFF);
			m_dataLength = m_dataBuffer[TNSPacketOffsets.NSPCNLEN] & 0xFF;
			m_dataLength <<= 8;
			m_dataLength |= m_dataBuffer[TNSPacketOffsets.NSPCNLEN + 1] & 0xFF;
			m_dataOffset = m_dataBuffer[TNSPacketOffsets.NSPCNOFF] & 0xFF;
			m_dataOffset <<= 8;
			m_dataOffset |= m_dataBuffer[TNSPacketOffsets.NSPCNOFF + 1] & 0xFF;
			_ = m_dataBuffer[TNSPacketOffsets.NSPCNFL0];
			_ = m_dataBuffer[TNSPacketOffsets.NSPCNFL1];
			if (num >= 310)
			{
				int num5 = m_dataBuffer[TNSPacketOffsets.NSPCNADL] & 0xFF;
				num5 <<= 8;
				num5 |= m_dataBuffer[TNSPacketOffsets.NSPCNADL + 1] & 0xFF;
				if (num5 > 0)
				{
					int num6 = m_dataBuffer[TNSPacketOffsets.NSPCNADF] & 0xFF;
					num6 <<= 8;
					num6 |= m_dataBuffer[TNSPacketOffsets.NSPCNADF + 1] & 0xFF;
					m_sessionCtx.m_reconAddr = Conv.GetInstance(871).ConvertBytesToString(m_dataBuffer, num6, num5);
					if ((m_flags & Packet.NSPFSID) > 0)
					{
						m_length -= Packet.NSPSID_SZ;
						m_sessionCtx.m_SID = new byte[Packet.NSPSID_SZ];
						Buffer.BlockCopy(m_dataBuffer, m_length, m_sessionCtx.m_SID, 0, Packet.NSPSID_SZ);
					}
				}
			}
			if (num4 < m_sessionCtx.m_transportDataUnit)
			{
				m_sessionCtx.m_transportDataUnit = num4;
			}
			if (num3 < m_sessionCtx.m_sessionDataUnit)
			{
				m_sessionCtx.m_sessionDataUnit = num3;
			}
			if (num <= m_sessionCtx.m_myversion)
			{
				m_sessionCtx.m_myversion = num;
				if (num < m_sessionCtx.m_loversion)
				{
					throw new NetworkException(12618);
				}
			}
			else if (m_sessionCtx.m_myversion < num2)
			{
				throw new NetworkException(12618);
			}
			m_sessionCtx.m_loversion = Math.Max(m_sessionCtx.m_loversion, num2);
			byte[] array = ExtractData();
			if (array != null)
			{
				m_sessionCtx.m_connectData = Conv.GetInstance(871).ConvertBytesToString(array, 0, m_dataLength);
			}
			if (m_sessionCtx.m_transportDataUnit < m_sessionCtx.m_sessionDataUnit)
			{
				m_sessionCtx.m_sessionDataUnit = m_sessionCtx.m_transportDataUnit;
			}
		}
	}
}
